/**
 * 
 */
package steffens.java.gui.defaultui.bar;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JProgressBar;
import javax.swing.plaf.basic.BasicProgressBarUI;

import steffens.java.gui.defaultui.bar.listener.ProgressAdapter;
import steffens.java.gui.defaultui.general.DefaultBar;

/**
 * @author Steffen Baumann
 * @version 1.0 
 *
 */
public class ProgressStatusBar extends DefaultBar implements ProgressAdapter{

	private static final int MIN = 0;
	private static final int MAX = Integer.MAX_VALUE;
	private double progress = 0.0;	
	
	private JProgressBar progressBar = new JProgressBar(MIN,MAX);
	private Dimension progressSize = new Dimension(100,16);
	private static final int DEFAULT_INSET_X = 2;
	private static final int DEFAULT_INSET_Y = 0;
	private Dimension insets = new Dimension(DEFAULT_INSET_X, DEFAULT_INSET_Y);
	private boolean valuePrinted = false;
	private int precision = 0;
	 
	
	public static final Color DEFAULT_PROGRESS_COLOR = Color.GREEN.darker();
	public static final Color DEFAULT_UNREACHED_COLOR = DEFAULT_PROGRESS_COLOR;
	public static final Color DEFAULT_REACHED_COLOR = DEFAULT_PROGRESS_COLOR.brighter();
	
	private Color textUnreachedColor = DEFAULT_UNREACHED_COLOR;
	private Color textReachedColor = DEFAULT_REACHED_COLOR;
	
	private BasicProgressBarUI textColors = new BasicProgressBarUI(){
		@Override
		protected Color getSelectionBackground() {
			return textUnreachedColor;
		}
		@Override
		protected Color getSelectionForeground() {
			return textReachedColor;
		}
	};
	
	public ProgressStatusBar() {
		this("Test");
	}
	/**
	 * 
	 */
	public ProgressStatusBar(String text) {
		setLayout();
		setProgressColor(DEFAULT_PROGRESS_COLOR);
		updateBar();
	}

	private void setLayout(){
		getBarContainer().setLayout(new GridBagLayout());
	}
	
	@Override
	public void updateBar() {
		Container con = getBarContainer();
		Dimension minimalSize = getMinimumDimension();
		con.setMinimumSize(minimalSize);
		con.setPreferredSize(minimalSize);
		validateBar(con);
		progressBar.setBackground(getBackground());
		setProgressColor(getProgressColor());
		progressBar.setUI(textColors);
		con.validate();
		Container parent = con.getParent();
		if(parent != null){
			parent.validate();
		}
		if(getParentNotifier() != null) getParentNotifier().notifyParentAboutCahnge();
	}
	private Dimension getFieldContainerDimension() {
		int progressWidth = progressSize.width;
		int progressHeight = progressSize.height;
		int insetsHeight = insets.height;
		int insetsWidth = insets.width;
		return new Dimension((progressWidth+insetsWidth)+insetsWidth,insetsHeight*2+progressHeight);
	}

	public Dimension getMinimumDimension(){
		return getFieldContainerDimension();
	}

	private void validateBar(Container con){
		progressBar.setSize(progressSize);
		progressBar.setPreferredSize(progressSize);
		progressBar.setMinimumSize(progressSize);
		progressBar.setMaximumSize(progressSize);
		
		getBarContainer().add(progressBar, getConstraints());
	}
	
	private GridBagConstraints getConstraints(){
		GridBagConstraints placement = new GridBagConstraints();
		placement.anchor = GridBagConstraints.LINE_START;
		placement.gridx = 0;
		placement.gridy = 0;
		placement.weightx = 0.5;
		placement.fill = GridBagConstraints.HORIZONTAL;
		return placement;
	}
	@Override
	public double receiveCurrentProgress() {
		return progress;
	}
	@Override
	public void setCurrentValue(double progress) {
		this.progress = progress;
		this.progressBar.setValue((int)(progress*MAX));
		if(valuePrinted){
			String format = "%."+precision+"f";
			progressBar.setString(String.format(format, (progress*100))+"%");
		}
	}
	public void setValuePrinted(boolean valuePrinted){
		progressBar.setStringPainted(valuePrinted);
		this.valuePrinted = valuePrinted;
		setCurrentValue(receiveCurrentProgress());
	}
	public void setPrecision(int precision){
		this.precision = precision;
	}
	public void setProgressBarSize(Dimension progressBarSize){
		this.progressSize = progressBarSize;
		updateBar();
	}
	public Dimension getProgressBarSize(){
		return this.progressSize;
	}
	/**
	 * @return the progressColor
	 */
	public Color getProgressColor() {
		return progressBar.getForeground();
	}
	/**
	 * @param progressColor the progressColor to set
	 */
	public void setProgressColor(Color progressColor) {
		this.progressBar.setForeground(progressColor);
	}
	public void setTextColors(Color unreachedText, Color reachedText){
		this.textUnreachedColor = unreachedText;
		this.textReachedColor = reachedText;
	}
	
}
